package org.javahispano.javacup.tacticas_aceptadas.Ota;

import java.awt.Color;
import org.javahispano.javacup.modelo.*;
import java.util.List;
import java.util.LinkedList;

public class Vagon implements Tactica {

        Posicion alineacion1[]=new Posicion[]{
        new Posicion(10.223776223776223,-33.970588235294116),
        new Posicion(-10.6993006993007,-33.257918552036195),
        new Posicion(21.636363636363637,-19.004524886877828),
        new Posicion(-24.013986013986013,-20.192307692307693),
        new Posicion(-0.7132867132867133,-20.192307692307693),
        new Posicion(-0.23776223776223776,-50.124434389140276),
        new Posicion(-13.076923076923078,-13.778280542986426),
        new Posicion(-0.23776223776223776,-1.1877828054298643),
        new Posicion(-12.363636363636363,-0.9502262443438915),
        new Posicion(10.461538461538462,-13.778280542986426),
        new Posicion(15.454545454545453,-1.1877828054298643)
    };

    Posicion alineacion2[]=new Posicion[]{
        new Posicion(-16.643356643356643,-21.855203619909503),
        new Posicion(-12.839160839160838,-36.82126696832579),
        new Posicion(0.7132867132867133,-23.518099547511312),
        new Posicion(14.027972027972028,-36.82126696832579),
        new Posicion(12.363636363636363,-16.391402714932127),
        new Posicion(-0.23776223776223776,-50.59954751131222),
        new Posicion(-23.3006993006993,-7.364253393665159),
        new Posicion(22.349650349650346,-4.751131221719457),
        new Posicion(-8.321678321678322,-4.98868778280543),
        new Posicion(8.321678321678322,-4.98868778280543),
        new Posicion(-0.23776223776223776,-9.97737556561086)
    };

    Posicion alineacion3[]=new Posicion[]{
        new Posicion(-1.6643356643356644,-50.124434389140276),
        new Posicion(2.6153846153846154,-50.124434389140276),
        new Posicion(-12.363636363636363,-39.43438914027149),
        new Posicion(10.461538461538462,-38.72171945701358),
        new Posicion(-1.4265734265734267,-35.39592760180996),
        new Posicion(0.7132867132867133,-50.36199095022624),
        new Posicion(-23.776223776223777,-25.656108597285066),
        new Posicion(21.3986013986014,-25.18099547511312),
        new Posicion(-13.552447552447552,-19.95475113122172),
        new Posicion(11.412587412587413,-19.717194570135746),
        new Posicion(-1.6643356643356644,-15.678733031674208)
    };

    Posicion alineacion4[]=new Posicion[]{
        new Posicion(-4.5174825174825175,-44.18552036199095),
        new Posicion(4.5174825174825175,-44.42307692307692),
        new Posicion(-9.272727272727272,-36.82126696832579),
        new Posicion(10.937062937062937,-37.05882352941177),
        new Posicion(0.0,-35.8710407239819),
        new Posicion(-0.4755244755244755,-50.83710407239819),
        new Posicion(-21.16083916083916,-19.717194570135746),
        new Posicion(22.11188811188811,-11.877828054298643),
        new Posicion(-11.65034965034965,-10.214932126696834),
        new Posicion(8.55944055944056,-9.739819004524888),
        new Posicion(0.951048951048951,-3.3257918552036196)
    };

    Posicion alineacion5[]=new Posicion[]{
        new Posicion(-11.174825174825173,-37.77149321266968),
        new Posicion(14.503496503496503,-36.58371040723982),
        new Posicion(-14.265734265734267,-20.90497737556561),
        new Posicion(15.454545454545453,-21.855203619909503),
        new Posicion(1.4265734265734267,-15.441176470588236),
        new Posicion(-0.23776223776223776,-50.83710407239819),
        new Posicion(-25.678321678321677,-9.264705882352942),
        new Posicion(24.251748251748253,-6.651583710407239),
        new Posicion(-11.888111888111888,-3.5633484162895925),
        new Posicion(13.076923076923078,0.23755656108597287),
        new Posicion(0.4755244755244755,0.9502262443438915)
    };

    Posicion alineacion6[]=new Posicion[]{
        new Posicion(-12.125874125874127,-26.368778280542987),
        new Posicion(8.083916083916083,-27.31900452488688),
        new Posicion(-18.545454545454543,-11.877828054298643),
        new Posicion(14.265734265734267,-11.402714932126697),
        new Posicion(-1.4265734265734267,-4.751131221719457),
        new Posicion(-0.23776223776223776,-50.83710407239819),
        new Posicion(-13.314685314685315,4.513574660633484),
        new Posicion(10.461538461538462,5.226244343891403),
        new Posicion(-9.510489510489512,10.690045248868778),
        new Posicion(4.9930069930069925,12.352941176470589),
        new Posicion(-0.7132867132867133,17.104072398190045)
    };

    Posicion alineacion7[]=new Posicion[]{
        new Posicion(-14.74125874125874,-14.490950226244346),
        new Posicion(8.55944055944056,-15.678733031674208),
        new Posicion(-19.97202797202797,0.9502262443438915),
        new Posicion(11.65034965034965,2.8506787330316743),
        new Posicion(-2.8531468531468533,10.214932126696834),
        new Posicion(-0.23776223776223776,-50.83710407239819),
        new Posicion(-13.79020979020979,17.816742081447966),
        new Posicion(8.797202797202797,18.766968325791854),
        new Posicion(-4.9930069930069925,24.705882352941178),
        new Posicion(4.5174825174825175,31.119909502262445),
        new Posicion(-10.461538461538462,31.83257918552036)
    };

    Posicion alineacion8[]=new Posicion[]{
        new Posicion(-14.265734265734267,-13.303167420814479),
        new Posicion(10.937062937062937,-11.877828054298643),
        new Posicion(-17.356643356643357,6.651583710407239),
        new Posicion(13.552447552447552,7.601809954751132),
        new Posicion(-2.13986013986014,14.96606334841629),
        new Posicion(-0.23776223776223776,-50.83710407239819),
        new Posicion(-12.601398601398602,27.556561085972852),
        new Posicion(8.321678321678322,26.84389140271493),
        new Posicion(-9.986013986013985,36.34615384615385),
        new Posicion(10.223776223776223,36.58371040723982),
        new Posicion(-0.4755244755244755,40.147058823529406)
    };










   public class TacticaDetalleImpl implements TacticaDetalle {

        public String getNombre() {
            return "Vagon";
        }

        public String getPais() {
            return "España";
        }

        public String getEntrenador() {
            return "Ota";
        }

        public Color getColorCamiseta() {
            return new Color(10, 183, 221);
        }

        public Color getColorPantalon() {
            return new Color(154, 32, 153);
        }

        public Color getColorFranja() {
            return new Color(111, 151, 36);
        }

        public Color getColorCalcetas() {
            return new Color(78, 162, 243);
        }

        public Color getColorPortero() {
            return new Color(22, 188, 102        );
        }

        public EstiloUniforme getEstilo() {
            return EstiloUniforme.FRANJA_VERTICAL;
        }

        public Color getColorCamiseta2() {
            return new Color(68, 105, 121);
        }

        public Color getColorPantalon2() {
            return new Color(219, 21, 194);
        }

        public Color getColorFranja2() {
            return new Color(4, 179, 251);
        }

        public Color getColorCalcetas2() {
            return new Color(72, 96, 94);
        }

        public Color getColorPortero2() {
            return new Color(3, 34, 47        );
        }

        public EstiloUniforme getEstilo2() {
            return EstiloUniforme.SIN_ESTILO;
        }

        class JugadorImpl implements JugadorDetalle {

            String nombre;
            int numero;
            Color piel, pelo;
            double velocidad, remate, presicion;
            boolean portero;
            Posicion posicion;

            public JugadorImpl(String nombre, int numero, Color piel, Color pelo,
                    double velocidad, double remate, double presicion, boolean portero) {
                this.nombre=nombre;
                this.numero=numero;
                this.piel=piel;
                this.pelo=pelo;
                this.velocidad=velocidad;
                this.remate=remate;
                this.presicion=presicion;
                this.portero=portero;
            }

            public String getNombre() {
                return nombre;
            }

            public Color getColorPiel() {
                return piel;
            }

            public Color getColorPelo() {
                return pelo;
            }

            public int getNumero() {
                return numero;
            }

            public boolean esPortero() {
                return portero;
            }

            public double getVelocidad() {
                return velocidad;
            }

            public double getRemate() {
                return remate;
            }

            public double getPresicion() {
                return presicion;
            }

        }

        public JugadorDetalle[] getJugadores() {
            return new JugadorDetalle[]{
                new JugadorImpl("Jugador", 1, new Color(255,200,150), new Color(50,0,0),0.49d,0.96d,0.5d, false),
                new JugadorImpl("Jugador", 2, new Color(255,200,150), new Color(50,0,0),0.5d,1.0d,0.5d, false),
                new JugadorImpl("Jugador", 3, new Color(255,200,150), new Color(50,0,0),1.0d,1.0d,0.5d, false),
                new JugadorImpl("Jugador", 4, new Color(255,200,150), new Color(50,0,0),1.0d,1.0d,1.0d, false),
                new JugadorImpl("Jugador", 5, new Color(255,200,150), new Color(50,0,0),1.0d,0.5d,1.0d, false),
                new JugadorImpl("Jugador", 6, new Color(255,200,150), new Color(50,0,0),1.0d,1.0d,1.0d, true),
                new JugadorImpl("Jugador", 7, new Color(255,200,150), new Color(50,0,0),1.0d,0.5d,1.0d, false),
                new JugadorImpl("Jugador", 8, new Color(255,200,150), new Color(50,0,0),1.0d,0.5d,1.0d, false),
                new JugadorImpl("Jugador", 9, new Color(255,200,150), new Color(50,0,0),1.0d,1.0d,0.5d, false),
                new JugadorImpl("Jugador", 10, new Color(255,200,150), new Color(50,0,0),1.0d,0.99d,0.5d, false),
                new JugadorImpl("Jugador", 11, new Color(255,200,150), new Color(50,0,0),1.0d,0.99d,0.5d, false)
            };
        }
    }

    TacticaDetalle detalle=new TacticaDetalleImpl();
    public TacticaDetalle getDetalle() {
        return detalle;
    }

    public static final int DEFENSA_EXTREMA = 0;
    public static final int DEFENSA_APRETADA = 1;
    public static final int DEFENSA_RECUPERANDO = 2;
    public static final int ATAQUE_MEDIO = 3;
    public static final int ATAQUE_CERCA = 4;
    public static final int ATAQUE_MUYCERCA = 5;

    public Posicion[] getPosicionSaca(SituacionPartido sp) {
     return alineacion1;
    }

    public Posicion[] getPosicionRecive(SituacionPartido sp) {
     return alineacion2;
    }

   

    private void colocarAlineacion(List<Comando> c,Posicion l[])
    {
        for ( int i = 0; i < l.length; i++)
            c.add(new ComandoIrA(i,l[i]));
    }

    LinkedList<Comando> comandos = new LinkedList<Comando>();
    MiSituacion MiSit = null;
    public List<Comando> ejecutar(SituacionPartido sp) {
        comandos.clear();
        // Averiguamos todos los datos (pintamos el estado actual del juego)
        if ( MiSit == null )
          MiSit = new MiSituacion(sp);
        else
          MiSit.actualizar(sp);
        // Ponemos todos los movimientos
        if ( sp.saco() == true){
            //System.out.println("Estamos sacando");
            int jugador = irABalon(comandos,MiSit,sp);
            if ( jugador != -1 )
            {
             if ( jugador == MiSit.miPortero())
              despejar(comandos,MiSit,sp,jugador);
             else
              pasar(comandos,MiSit,sp);
            }
        }
        else
        {
         // Aplicamos la tactica
         if ( (MiSit.getPelotaEnMiCampo() == true) && (MiSit.getTengoPelota() == false) )
         {
             // Estamos en defensa situamos los jugadores
             if (MiSit.getEnSuperPeligro() == true)
             {
              // Estamos en peligro todos a la porteria
              colocarAlineacion(comandos,MiSit.getPosicion(DEFENSA_EXTREMA));
              irABalon(comandos,MiSit,sp);
              pasar(comandos,MiSit,sp);
             }
             else if(MiSit.getEnPeligro() == true) // Cuidado estan muy cerca
             {
              colocarAlineacion(comandos,MiSit.getPosicion(DEFENSA_APRETADA));
              irABalon(comandos,MiSit,sp);
              avanzar(comandos,MiSit,sp);
             }
             else // Defensa relajada
             {
              colocarAlineacion(comandos,MiSit.getPosicion(DEFENSA_RECUPERANDO));
              irABalon(comandos,MiSit,sp);
              avanzar(comandos,MiSit,sp);
             }
         }
         else
         {
             if ( MiSit.podemosMarcar() == true)
             {
                 // Podemos chutar
                 colocarAlineacion(comandos,MiSit.getPosicion(ATAQUE_MUYCERCA));
                 irABalon(comandos,MiSit,sp);
                 chutar(comandos,MiSit,sp);
             }
              else if ( MiSit.getBalorSeAcerca() == false  )
             {
                 // Nos acercamos nosotros
                 colocarAlineacion(comandos,MiSit.getPosicion(ATAQUE_CERCA));
                 irABalon(comandos,MiSit,sp);
                 avanzar(comandos,MiSit,sp);
             }
             else
             {
                 // Se acerta el contrario
                 colocarAlineacion(comandos,MiSit.getPosicion(ATAQUE_MEDIO));
                 irABalon(comandos,MiSit,sp);
                 avanzar(comandos,MiSit,sp);
             }

         }
         // Movemos el portero en todas las situacion tanto ataque como  defensa
         portero(comandos,MiSit,sp);
        }
 
        return comandos;
    }

    class MiSituacion
    {
        private boolean ganando = false;
        private boolean pelotaMiCampo = false;
        private boolean tengoLaPelota = false;
        private int     quienTienePelota = 0;
        private boolean balonSeAcerca = false;
        private Posicion balonAnterior = null;
        private boolean enPeligro = false;
        private boolean enSuperPeligro = false;
        private boolean podemosMarcar = false;
        private int porteroRival = 0;
        private int miPortero = 0;
        private int posActual = 0;
        private int avanza = 0;
        private double Yportero = 0;
        

        MiSituacion(SituacionPartido sp){
            for ( int i = 0; i < sp.detalleJugadoresRivales().length;i++)
                if (sp.detalleJugadoresRivales()[i].esPortero() == true)
                    porteroRival = i;
            for ( int i = 0; i < sp.detalleMisJugadores().length;i++)
                if (sp.detalleMisJugadores()[i].esPortero() == true)
                    miPortero = i;
            // Averiguamos el signo de avance
            if ( sp.misJugadores()[miPortero].getY() < sp.rivales()[porteroRival].getY())
            {
                Yportero = Constantes.posteIzqArcoInf.getY() + 2;
                avanza = 2;
            }
            else
            {
                Yportero = Constantes.posteDerArcoInf.getY() -2 ;
                avanza = -2;
            }
            actualizar(sp);
        }

        public void actualizar(SituacionPartido sp){
         ganando = (sp.golesPropios() - sp.golesRival()) > 0;
         pelotaMiCampo = (sp.balon().distancia(sp.misJugadores()[miPortero])) < 40;
         enPeligro = (sp.balon().distancia(sp.misJugadores()[miPortero])) < 25;
         enSuperPeligro = (sp.balon().distancia(sp.misJugadores()[miPortero])) < 10;
         podemosMarcar = (sp.balon().distancia(sp.rivales()[porteroRival]) < 30);
         tengoLaPelota = false;
         if ( -1 != puedoRematar(sp) )
          tengoLaPelota = true;

          if ( balonAnterior != null ){
             if ( balonAnterior.distancia(sp.misJugadores()[miPortero]) >
                  sp.balon().distancia(sp.misJugadores()[miPortero]) )
              balonSeAcerca = true;
             else
              balonSeAcerca = false;
          }
          balonAnterior = sp.balon();
        }
        public boolean getGanando() { return(ganando);}
        public boolean getPelotaEnMiCampo() { return(pelotaMiCampo);}
        public boolean getTengoPelota() { return(tengoLaPelota);}
        public int getQuienTienePelota() { return(quienTienePelota);}
        public boolean getBalorSeAcerca() { return(balonSeAcerca);}
        public boolean getEnPeligro() { return(enPeligro);}
        public boolean getEnSuperPeligro() { return(enSuperPeligro);}
        public boolean podemosMarcar() { return(podemosMarcar);}
        public int miPortero() { return(miPortero);}
        public int suPortero() { return(porteroRival);}
        public int getAvanza() { return(avanza);}
        public double getYPortero() { return(Yportero);}
        private String getText(int id){
        switch(id)
        {
           case DEFENSA_EXTREMA: return("DEFENSA_EXTREMA");
           case DEFENSA_APRETADA:  return("DEFENSA_APRETADA");
           case DEFENSA_RECUPERANDO:  return("DEFENSA_RECUPERANDO");
           case ATAQUE_MEDIO:  return("ATAQUE_MEDIO");
           case ATAQUE_CERCA: return("ATAQUE_CERCA");
           case ATAQUE_MUYCERCA: return("ATAQUE_MUYCERCA");
        }
         return("???");
        }
        public Posicion[] getPosicion(int id){
        //if ( id != posActual )
        //    System.out.println("Nueva alineacion " + getText(posActual)+ " -> " +getText(id) );
        posActual = id;
        switch(id)
        {
           case DEFENSA_EXTREMA:  return(alineacion3);
           case DEFENSA_APRETADA:  return(alineacion4);
           case DEFENSA_RECUPERANDO:   return(alineacion5);
           case ATAQUE_MEDIO:  return(alineacion6);
           case ATAQUE_CERCA:    return(alineacion7);
           case ATAQUE_MUYCERCA:   return(alineacion8);
        }
        return(alineacion5);
    }
    }

    // Indica si el jugador puede rematar
    private boolean puedoRematar(SituacionPartido sp, int jugador){
        int a[] = sp.puedenRematar();
        for (int i = 0; i < a.length ; i++)
        {
          if ( a[i] == jugador)
               return(true);
        }
        return(false);
    }

    // Indica si algun jugador puede rematar
    private int puedoRematar(SituacionPartido sp){
    int a[] = sp.puedenRematar();
    if ( a.length > 0)
     return(a[0]);
     else
     return(-1);
    }
    private boolean puedenRematar(SituacionPartido sp){
    int a[] = sp.puedenRematarRival();
    if ( a.length > 0)
     return(true);
     else
     return(false);
    }
    // Indica a que pareja se le tiene que pasar
    private int pareja(int jugador){
        switch(jugador){
            case 0: return(4);
            case 1: return(3);
            case 2: return(6);
            case 3: return(2);
            case 4: return(6);
            case 5: return(0);
            case 6: return(8);
            case 7: return(9);
            case 8: return(7);
            case 9: return(10);
            case 10: return(9);
        }
        return(10);
    }

    // Compartamiento del portero
    private void portero(List<Comando> lComando,MiSituacion Msp,SituacionPartido sp)
    {
        // Miramos si podemos rematar, si podemos despejamos lo mas arriba posible
        if ( true == puedoRematar(sp,Msp.miPortero()))
        {
         despejar(lComando,Msp,sp,Msp.miPortero());
        }
        else
        {
        // Posicionamos el portero, seguimos la pelota
        Posicion lPos = new Posicion(sp.misJugadores()[Msp.miPortero()]);
        lPos = lPos.setPosicion( sp.balon().getX(),Msp.getYPortero());
        if ( lPos.getX() <  Constantes.posteIzqArcoInf.getX() )
          lPos = lPos.setPosicion( Constantes.posteIzqArcoInf.getX(),Msp.getYPortero());
        else if ( lPos.getX() >  Constantes.posteDerArcoInf.getX())
          lPos = lPos.setPosicion( Constantes.posteDerArcoInf.getX(),Msp.getYPortero());
        lComando.add(new ComandoIrA(Msp.miPortero(),lPos));
        }
    }

    // Despej el balon lo mas lejos que puede
    private void despejar(List<Comando> lComando,MiSituacion Msp,SituacionPartido sp,int jugador)
    {
     //System.out.println("Despejamos");
     lComando.add(new ComandoGolpearBalon(jugador,sp.rivales()[Msp.suPortero()],1,true));
    }

    // El jugador mas cercano se acerca a la pelota
    private int irABalon(List<Comando> lComando,MiSituacion Msp,SituacionPartido sp)
    {
      int i = sp.balon().indiceMasCercano(sp.misJugadores());
      lComando.add(new ComandoIrA(i,sp.balon()));
      return( i );
    }

    private void avanzar(List<Comando> lComando,MiSituacion Msp,SituacionPartido sp)
    {
      int origen = puedoRematar(sp);
      if ( origen!= -1)
      {
        //System.out.println("Avanza jugador " + origen);
        //System.out.println("Pos actual " + sp.misJugadores()[origen].getX() + " " +  sp.misJugadores()[origen].getY() + " " );
        Posicion ll = sp.misJugadores()[origen].setPosicion(sp.misJugadores()[origen].getX(),
                sp.misJugadores()[origen].getY() + Msp.getAvanza());
        //System.out.println("Pos final " + ll.getX() + " " +  ll.getY());
        lComando.add(new ComandoGolpearBalon(origen,ll,0.4,false));
      }
    }

    private void pasar(List<Comando> lComando,MiSituacion Msp,SituacionPartido sp)
    {
      int origen = puedoRematar(sp);
      if ( origen!= -1)
      {
       int jugadorDestino = pareja(origen);
       Posicion destino = sp.misJugadores()[jugadorDestino];
       lComando.add(new ComandoGolpearBalon(origen,destino,1,false));
      }
    }

    private void chutar(List<Comando> lComando,MiSituacion Msp,SituacionPartido sp)
    {
      int j = puedoRematar(sp);
      if ( j != -1)
      {
         //System.out.println("Chutoooo");
         Posicion l = sp.rivales()[Msp.porteroRival];
         l.setPosicion( ((Constantes.posteDerArcoInf.getX()-Constantes.posteIzqArcoInf.getX())/2),l.getY());
         lComando.add(new ComandoGolpearBalon(j,l ,0.8,true));
       }
    }

    

    

}